<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Document</title>
    </head>
    <body>
        <script>
            //T1
            // function fn1() {
            //     console.log(1); // 2. fn1调用后，这里是同步，所以首先是打印1
            //     fn2(); // 3. fn2被调用
            // }
            // function fn2() {
            //     // 4. setTimeout属于异步中的宏任务，等待被加入宏任务队列，然后继续执行下面代码
            //     setTimeout(() => {
            //         console.log(2);
            //     }, 100);
            //     // 5. console.log(3)直接执行，打印3
            //     console.log(3);
            //         //  6. new Promise是同步，所以直接打印4
            //     new Promise(function (res, rej) {

            //         console.log(4);
            //         res(5);
            //         // 7. then方法属于异步中的微任务，加入微任务队列，此时已无正在执行的同步代码，then开始被压入执行栈执行 打印5，然后微任务执行完毕，开始执行宏任务，队列中的宏任务依次入栈执行 执行上面加入宏任务队列的定时器任务，打印5
            //     }).then((res) => {
            //         console.log(res); //5
            //     });
            // }
            // fn1(); // 1. fn1调用

            //T2
            // // 1.setTimeout等待后被加入宏任务队列， 不执行内部代码，继续向下执行代码
            // setTimeout(() => {
            //     console.log(1); // 4. 执行后直接打印1
            //     // 5. 遇到setTimeout，继续加入宏任务队列
            //     setTimeout(() => {
            //         console.log(2);
            //     }, 0);
            //     // 6. 遇到setTimeout，继续加入宏任务队列， 此时当前的宏任务执行完毕，开始执行下一个宏任务，也就是上一个加入队列的settimeout，打印2，最后执行当前这个，打印3
            //     setTimeout(() => {
            //         console.log(3);
            //     }, 0);
            // }, 0);
            // //2. 下面这个setTimeout也等待后被加入宏任务队列， 继续向下执行代码
            // setTimeout(() => {
            //     console.log(4);
            // }, 0);
            // // 3. 已无同步代码，微任务队列中无微任务，开始执行宏任务，执行第一个setTimeout
            // // 1 4 2 3

            //   //T3
            console.log("script start");
            setTimeout(() => {
                console.log("timeout1");
            }, 10);
            new Promise((resolve) => {
                console.log("promise1");
                resolve();
                setTimeout(() => {
                    console.log("timeout2");
                }, 10);
            }).then(() => {
                console.log("then1");
            });
            console.log("script end");
            // 1. 首先是直接打印script start
            // 2. 遇到第一个定时器，等待后加入宏任务队列
            // 3. new promise属于同步，所以直接打印promise1
            // 4. 遇到第二个定时器，等待后加入宏任务队列
            // 5. then方法属于微任务，加入微任务队列
            // 6. 直接打印script end
            // 7. 同步代码执行完毕，开始调用执行微任务队列中的微任务，then方法执行，打印then1
            // 8. 微任务执行完毕，开始调用执行宏任务队列中的异步任务，首先是第一个定时器，打印timeout1，然后是第二个定时器，打印timeout2
            //   /*；
            //   同步：script start   promise1   script end
            //   异步
            //     微：then1
            //     宏：timeout1   timeout2
            //   */

            //   //T4
            // async function async1() {
            //     console.log("A");
            //     async2();
            //     console.log("B");
            // }
            // async function async2() {
            //     console.log("C");
            // }
            // console.log("D");
            // setTimeout(() => {
            //     console.log("F");
            // }, 0);
            // async1();
            // new Promise((resolve) => {
            //     console.log("G");
            //     resolve();
            // }).then(() => {
            //     console.log("H");
            // });
            // console.log("I");
            // 1. 首先是打印D
            // 2. 遇到定时器，等待后加入宏任务队列
            // 3. 调用函数async1，async关键字声明的函数在没有wait时和普通函数无区别，于是直接打印A， 然后调用async2函数， 打印C， 最后打印B
            // 4. Promise实例中的打印函数执行，打印G
            // 5. then方法加入微任务队列
            // 6. 打印I
            // 7. 同步代码执行完毕，then方法调用执行，打印H，微任务队列任务执行完毕，调用执行宏任务队列中的定时器，打印F
            //   /*
            //   同步：D A C B G I
            //   异步
            //     微：H
            //     宏：F
            //   */

            //T5
            // async function haha() {
            //     console.log(1);
            //     //微任务
            //     await xixi();
            //     console.log(2);
            //     console.log(4);
            //     heihei();
            // }
            // async function xixi() {
            //     console.log(3);
            //     //宏任务
            //     setTimeout(() => {
            //         console.log(6);
            //     }, 0);
            // }
            // function heihei() {
            //     console.log(5);
            // }
            // haha();
            // 1. 调用haha
            // 2. haha中首先打印1
            // 3. 执行await， await后面的代码要放在微任务之前执行，此时先执行xixi
            // 4. 执行xixi，首先打印3，遇到定时器，加入宏任务队列
            // 5. 此时同步代码执行完毕，开始执行宏任务队列，首先打印出await后的2和4，然后执行heihei，打印出5
            // 6. 最后执行宏任务队列中的函数，打印6
            // //1 3 2 4 5 6

            //   //T6
            //   async function async1() {
            //     console.log("async1 start");
            //     //在async函数中，遇到await 会继续执行其他代码 再将await后面的代码放入微任务队列中
            //     await async2();
            //     console.log("async1 end"); //
            //   }
            //   async function async2() {
            //     console.log("async2");
            //   }
            //   console.log("script start");
            //   setTimeout(() => {
            //     console.log("setTimeout");
            //   }, 0);
            //   async1();
            //   new Promise(function (resolve) {
            //     console.log("promise1");
            //     resolve();
            //   }).then(function () {
            //     console.log("promise2");
            //   });
            //  1. 首先打印同步script start
            //  2. 然后遇到第一个定时器，将定时器加入宏任务队列
            //  3. 执行async1， 打印同步代码async1 start
            //  4. 执行awiat async2 打印async2， 将后面代码放入微任务队列前端
            //  5. 打印new Promise中的promise1
            //  6. then方法加入微任务队列中，
            //  7. 此时同步代码执行完毕， 执行微任务队列中的任务，先执行await后的代码，打印async1 end， 在执行then方法打印promise2
            //  8. 最后执行宏任务队列中的函数，打印setTimeout
            //   /*
            //   同步：script start      async1 start  async2      promise1
            //   异步：
            //     微：async1 end      promise2
            //     宏：setTimeout
            //   */
        </script>
    </body>
</html>
